package module.modbus.modbus4j;

import com.serotonin.io.serial.SerialParameters;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.*;
import com.serotonin.util.queue.ByteQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

/**
 * @author bingo
 * @Description    RTU方式数据的发送与接受 采用Modbus4j
 * @Date 2018/8/10
 */
public class RTU {

    private static  Logger logger = LoggerFactory.getLogger(RTU.class.getName());

    private static  int  BOUNT_RATE = 9600;

    private static  String COM_ID = "COM3";


    public static void main(String[] args) {

        ModbusMaster master = masterInit();
        try {
            master.init();
        } catch (ModbusInitException e) {
            e.printStackTrace();
        }
          //writeRegisters(master,1,0,new short[]{12345,0xb,0xc,0xd,0xe,0x9, 0x8, 0x7, 0x6});

        readRegister(master,1,0,5);
    }



    public  static  ModbusMaster  masterInit(){
        SerialParameters serialParameters = new SerialParameters();
        serialParameters.setCommPortId(COM_ID);
        serialParameters.setBaudRate(BOUNT_RATE);
        serialParameters.setParity(0);
        serialParameters.setDataBits(8);
        serialParameters.setStopBits(1);
        ModbusFactory modbusFactory = new ModbusFactory();
        ModbusMaster master = modbusFactory.createRtuMaster(serialParameters);
        return  master;
    }

    public static  void writeRegister (ModbusMaster mater ,int slaveId,int start,int value){

        long startTime = System.currentTimeMillis();
        try {
             WriteRegisterRequest writeRegisterRequest = new WriteRegisterRequest(slaveId,start,value);

            ByteQueue byteQueue = new ByteQueue(1024);
            writeRegisterRequest.write(byteQueue);
            logger.info("单个写请求方法码:{}",writeRegisterRequest.getFunctionCode());
            logger.info("requestQueueByte{}", byteQueue);
            System.out.println("do...............");
            WriteRegisterResponse writeRegistersResponse = (WriteRegisterResponse) mater.send(writeRegisterRequest);
           // byteQueue=new ByteQueue(1024);
            writeRegistersResponse.write(byteQueue);
            logger.info("ResponseQueueByte{}", byteQueue);
         } catch (ModbusTransportException e) {
            long endTime = System.currentTimeMillis();
            logger.info("等待时间:{}",(endTime-startTime));
            e.printStackTrace();
        }

    }

    /**
     *   批量写入寄存器
     *   @param mater   主机
     *   @param slaveId 从机id
     *   @param start   寄存器开始位置
     *   @param values  写入的值
     * */

    public  static void  writeRegisters(ModbusMaster mater ,int slaveId,int start,short[] values){
        try {
            WriteRegistersRequest writeRegisterRequest  = new WriteRegistersRequest(slaveId,start,values);

            WriteRegistersResponse writeRegistersResponse = (WriteRegistersResponse) mater.send(writeRegisterRequest);
            ByteQueue byteQueue = new ByteQueue(1024);
            writeRegisterRequest.write(byteQueue);
            logger.info("批量写请求方法码:{}",writeRegisterRequest.getFunctionCode());
            logger.info("queueByte{}", byteQueue);
        } catch (ModbusTransportException e) {
            e.printStackTrace();
        }

    }

    /**
     *   读寄存器的内容
     *   @param mater   主机
     *   @param slaveId 从机id
     *   @param start   寄存器开始位置
     *   @param len  读的数量
     * */

    public static void readRegister(ModbusMaster mater ,int slaveId,int start,int len){

        try {
            ReadHoldingRegistersRequest readHoldingRegistersRequest = new ReadHoldingRegistersRequest(slaveId,start,len);
            ReadHoldingRegistersResponse readHoldingRegistersResponse = (ReadHoldingRegistersResponse) mater.send(readHoldingRegistersRequest);
            logger.info("读数据请求方法码:{},响应方法码:{}",readHoldingRegistersRequest.getFunctionCode(),readHoldingRegistersResponse.getFunctionCode());
             ByteQueue byteQueue = new ByteQueue();
             readHoldingRegistersResponse.write(byteQueue);
            System.out.println(Arrays.toString(readHoldingRegistersResponse.getShortData()));

        } catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }




}
